
package com.ruoyi.runner;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ObjectUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.digital.FloatPreProcessor;
import com.ruoyi.common.utils.ip.NetworkUtils;
import com.ruoyi.common.utils.processor.ByteArrayProcessor;
import com.ruoyi.order.domain.MesDetectNode;
import com.ruoyi.order.domain.MesOrder;
import com.ruoyi.order.domain.MesProductNodeResult;
import com.ruoyi.order.domain.MesTopOrder;
import com.ruoyi.order.enums.NodeResultStatusEnum;
import com.ruoyi.order.enums.OrderStatusEnum;
import com.ruoyi.order.enums.TopOrderStatusEnum;
import com.ruoyi.order.proxy.factory.FactoryProxy;
import com.ruoyi.order.proxy.factory.req.QueryBarcodeRequset;
import com.ruoyi.order.proxy.factory.req.print.MarkLog;
import com.ruoyi.order.proxy.factory.req.print.PrintInfo;
import com.ruoyi.order.proxy.factory.req.print.PrintRequest;
import com.ruoyi.order.proxy.factory.req.send.KPSN;
import com.ruoyi.order.proxy.factory.req.send.SendBarcodeRequest;
import com.ruoyi.order.proxy.factory.res.BarcodeResponse;
import com.ruoyi.order.proxy.factory.res.ProcessDataResponse;
import com.ruoyi.order.service.IConfigService;
import com.ruoyi.order.service.IMesDetectNodeService;
import com.ruoyi.order.service.IMesProductNodeResultService;
import com.ruoyi.order.service.IMesTopOrderService;
import com.ruoyi.order.station.cmd.DB5400;
import com.ruoyi.order.station.cmd.DB5404;
import com.ruoyi.order.station.cmd.DB5411;
import com.ruoyi.order.station.handle.StationExchangeService;
import com.ruoyi.order.station.request.instance.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.*;

@Order(2)
@Lazy
@Slf4j
@Component
public class ScanPLCRunner implements ApplicationRunner {

    @Autowired
    private IConfigService configService;
    @Autowired
    private IMesDetectNodeService mesDetectNodeService;

    @Autowired
    private StationExchangeService stationExchangeService;
    @Autowired
    private IMesProductNodeResultService productNodeResultService;

    @Autowired
    private FactoryProxy factoryProxy;
    @Autowired
    private IMesTopOrderService mesOrderService;

/**
     * 启动时扫描PLC数据，循环执行，每次循环会遍历所有节点
     *
     * @param args
     * @throws Exception
     */

    @Override
    public void run(ApplicationArguments args) throws Exception {
        String productDataFlag = configService.selectConfigByKey("plc_product_data_flag");
        //边缘mes服务器IP
        String edge_mes_server_ip = configService.selectConfigByKey("edge_mes_server_ip");
        //工厂标识
        String werks = configService.selectConfigByKey("fwerks");
        //车间标识
        Integer workshopId = Integer.parseInt(configService.selectConfigByKey("work_shop_id"));
        //订单编码
        String orderNumber = configService.selectConfigByKey("order_number");
        //获取本地IP地址集合
        List<String> nodeIpList = NetworkUtils.readAllIPs();
        if (!nodeIpList.contains(edge_mes_server_ip)){
            log.info("本地IP地址集合：{}，不包含:{}",nodeIpList, edge_mes_server_ip);
            return ;
        }
        List<MesDetectNode>  nodes = mesDetectNodeService.selectMesDetectNodeList(new MesDetectNode());
        while (true) {

            Thread.sleep(1000);
            //获取当前检测订单信息
            MesTopOrder mesOrder = new MesTopOrder();
            mesOrder.setStatus(TopOrderStatusEnum.PRODUCING.getCode());
            List<MesTopOrder> mesOrderList = mesOrderService.selectMesTopOrderList(mesOrder);
            if (CollectionUtils.isEmpty(mesOrderList)) {
                continue;
            }
            MesTopOrder mesTopOrder = mesOrderList.get(0);
            //循环实现扫描PLC 生产数据
            if (productDataFlag.equals("true")) {
                long start = System.currentTimeMillis();
                DB5404 db5404 = stationExchangeService.getDB5404(nodes.get(0));
                DB5400 db5400 = new DB5400();
                DB5411 db5411 = new DB5411();
                db5411.setReady(true);
                stationExchangeService.writeDB5411(db5411, nodes.get(0));
                if (db5404.getDataRequest()){
                    log.info("PLC数据请求开始");
                    DB5405 db5405 = stationExchangeService.getDB5405(nodes.get(0));
                    ByteArrayProcessor.trimByteArrayFields(db5405);

                    DB5406 db5406 = stationExchangeService.getDB5406(nodes.get(0));
                    FloatPreProcessor.processFloatPrecision(db5406, 2);

                    DB5407 db5407 = stationExchangeService.getDB5407(nodes.get(0));
                    FloatPreProcessor.processFloatPrecision(db5407, 2);

                    DB5408 db5408 = stationExchangeService.getDB5408(nodes.get(0));
                    FloatPreProcessor.processFloatPrecision(db5408, 2);

                    DB5409 db5409 = stationExchangeService.getDB5409(nodes.get(0));
                    FloatPreProcessor.processFloatPrecision(db5409, 2);
                    Map<String, Object> map = ObjectUtils.mergeObj2Map(db5405, db5406, db5407, db5408, db5409);
                    log.info("PLC数据请求内容：{}", JSON.toJSONString(map));
                    MesProductNodeResult productNodeResult = new MesProductNodeResult();

                    productNodeResult.setTestDetail(JSON.toJSONString(map));
                    productNodeResult.setMachineModel(nodes.get(0).getMachineModel());
                    productNodeResult.setSortIndex(nodes.get(0).getSortIndex());
                    productNodeResult.setStationCode(nodes.get(0).getNodeCode());
                    productNodeResult.setStatus(NodeResultStatusEnum.VALID.getCode());
                    productNodeResult.setPartNumber(String.valueOf(map.get("sidePanelCode")));
                    productNodeResult.setTestResult(String.valueOf(map.get("result")));
                    productNodeResultService.insertMesProductNodeResult(productNodeResult);

                    //生产数据发送工厂
                    SendBarcodeRequest sendBarcodeRequest = new SendBarcodeRequest();
                    sendBarcodeRequest.setLineName(mesTopOrder.getLineNumber());
                    sendBarcodeRequest.setBarcode(productNodeResult.getPartNumber());
                    sendBarcodeRequest.setWorkShop(mesTopOrder.getWorkshopName());
                    sendBarcodeRequest.setDocno(mesTopOrder.getOrderNumber());
                    sendBarcodeRequest.setStationName(mesTopOrder.getOrderSeq());
                    List<KPSN> kpsnList = new ArrayList<>();
                    KPSN kpsn1 = new KPSN();
                    String pcbCode1 = new String(db5405.getPcbCode1(), "UTF-8");
                    pcbCode1 = StringUtils.trim(pcbCode1);
                    if (StringUtils.isNotEmpty(pcbCode1)){
                        kpsn1.setKpsn(pcbCode1);
                        kpsnList.add(kpsn1);
                    }
                    KPSN kpsn2 = new KPSN();
                    String pcbCode2 = new String(db5405.getPcbCode2(), "UTF-8");
                    pcbCode2 = StringUtils.trim(pcbCode2);
                    if (StringUtils.isNotEmpty(pcbCode2)){
                        kpsn2.setKpsn(pcbCode2);
                        kpsnList.add(kpsn2);
                    }
                    KPSN kpsn3 = new KPSN();
                    String pcbCode3 = new String(db5405.getPcbCode3(), "UTF-8");
                    pcbCode3 = StringUtils.trim(pcbCode3);
                    if (StringUtils.isNotEmpty(pcbCode3)){
                        kpsn3.setKpsn(pcbCode3);
                        kpsnList.add(kpsn3);
                    }
                    KPSN kpsn4 = new KPSN();
                    String pcbCode4 = new String(db5405.getPcbCode4(), "UTF-8");
                    pcbCode4 = StringUtils.trim(pcbCode4);
                    if (StringUtils.isNotEmpty(pcbCode4)){
                        kpsn4.setKpsn(pcbCode4);
                        kpsnList.add(kpsn4);
                    }
                    KPSN kpsn5 = new KPSN();
                    String pcbCode5 = new String(db5405.getCoverCode(), "UTF-8");
                    pcbCode5 = StringUtils.trim(pcbCode5);
                    if (StringUtils.isNotEmpty(pcbCode5)){
                        kpsn5.setKpsn(pcbCode5);
                        kpsnList.add(kpsn5);
                    }
                    sendBarcodeRequest.setKpsnList(kpsnList);
                    sendBarcodeRequest.setCreateTime(DateUtils.getTime());
                    boolean result = factoryProxy.sendProductData2Factory(sendBarcodeRequest);
                    if (result){
                        db5400.setFinishIO(true);
                    } else {
                        db5400.setFinishNIO(true);
                    }
                    stationExchangeService.writeDB5400(db5400, nodes.get(0));
                }
                //二维码请求
                if (db5404.getBarcodeRequest()){
                    QueryBarcodeRequset queryBarcodeRequset = new QueryBarcodeRequset();
                    queryBarcodeRequset.setWerks(mesTopOrder.getFactoryNumber());
                    queryBarcodeRequset.setDocno(mesTopOrder.getOrderNumber());
                    BarcodeResponse barcodeResponse = factoryProxy.queryBarcodeByOrder(queryBarcodeRequset);
                    DB5401 db5401 = new DB5401();
                    if (barcodeResponse != null){
                        if (barcodeResponse.getBarcode() != null) {
                            byte[] barcode = new byte[70];
                            System.arraycopy(barcodeResponse.getBarcode().getBytes(), 0, barcode, 0, barcodeResponse.getBarcode().getBytes().length);
                            db5401.setBarcode(barcode);
                        }
                        if (barcodeResponse.getVersion() != null) {
                            byte[] version = new byte[70];
                            System.arraycopy(barcodeResponse.getVersion().getBytes(), 0, version, 0, barcodeResponse.getVersion().getBytes().length);
                            db5401.setVersion(version);
                        }
                        if (barcodeResponse.getPcb() != null) {
                            byte[] pcb = new byte[70];
                            System.arraycopy(barcodeResponse.getProductName().getBytes(), 0, pcb, 0, barcodeResponse.getProductName().getBytes().length);
                            db5401.setPcb(pcb);
                        }
                        db5401.setResult(1);
                        //回传已打印条码给工厂MES
                        DB5410 db5410 = stationExchangeService.getDB5410(nodes.get(0));
                        PrintRequest printRequest = new PrintRequest();
                        List<MarkLog> marklogList = new ArrayList<>();
                        MarkLog markLog = new MarkLog();
                        List<PrintInfo> printInfoList = new ArrayList<>();
                        PrintInfo printInfo = new PrintInfo();
                        printInfo.setWorkOrderNo(mesTopOrder.getOrderNumber());
                        printInfo.setProductSn(barcodeResponse.getBarcode());
                        printInfo.setPrintSucess("成功");
                        printInfo.setReadSucess("成功");
                        printInfo.setPrintTime(DateUtils.getTime());
                        printInfoList.add(printInfo);
                        markLog.setPrintInfoList(printInfoList);

                        String machineNo = new String(db5410.getMachineNo(), StandardCharsets.UTF_8);
                        markLog.setMachineNo(StringUtils.trim(machineNo));
                        String machineStatus = new String(db5410.getMachineStatus(), StandardCharsets.UTF_8);
                        markLog.setMachineStatus(StringUtils.trim(machineStatus));
                        String oee = new String(db5410.getOee(), StandardCharsets.UTF_8);
                        markLog.setOee(StringUtils.trim(oee));
                        markLog.setGroupSn(barcodeResponse.getBarcode());
                        marklogList.add(markLog);
                        printRequest.setMarklog(marklogList);
                        ProcessDataResponse response = factoryProxy.sendPrint2Factory(printRequest);
                        if (response != null&& response.getCode()==0){
                            db5400.setBarcodeFinishIO(true);
                        } else {
                            db5400.setBarcodeFinishNIO(true);
                        }
                    }else {
                        db5401.setResult(2);
                        db5400.setBarcodeFinishNIO( true);
                    }
                    stationExchangeService.writeDB5401(db5401, nodes.get(0));
                    stationExchangeService.writeDB5400(db5400, nodes.get(0));
                }
                log.info("PLC数据扫描完成，耗时：{}", (System.currentTimeMillis() - start));
            }
        }
    }
}
